<?php
namespace App\Services;
use App\Helpers\Api\PayTrait;
use App\Helpers\Api\TtMiniTrait;
use App\Models\Balance;
use App\Models\Config;
use App\Models\Cookbook;
use App\Models\CookbookSnapshot;
use App\Models\MallOrder;
use App\Models\MallOrderProduct;
use App\Models\Order;
use App\Models\OrderSnapshot;
use App\Models\PackageSetting;
use App\Models\UnionOrder;
use App\Models\User;
use function Qbhy\TtMicroApp\Support\get_client_ip;

class OrderService {
    use PayTrait, TtMiniTrait;

    public static function is_buy($user_id, $entity_id) {
        return Order::where('user_id', $user_id)
            ->where('cookbook_id', $entity_id)
            ->where('status', Order::PAID_SUCCESS)->exists();
    }

    public static function create_pay($user_id, $entity_id, $pay_type, $product_type, $benefit_user) {
        $self = new self();
        $user = User::find($user_id);
        $discount = Config::getDiscount();
        if ($product_type == Order::PRODUCT_TYPE_VIP)
            $prefix = 'v';
        else if($product_type == Order::PRODUCT_TYPE_COOKBOOK)
            $prefix = 'c';
        else
            $prefix = 'd';

        $out_trade_no = create_order_no($prefix);
        $entity = null;
        if ($product_type == Order::PRODUCT_TYPE_COOKBOOK) {
            $exist = self::is_buy($user_id, $entity_id);
            if ($exist)
                throw new \Exception('已经购买过改商品');

            $model = new Cookbook();
            $entity = $model->find($entity_id);
            if ($user->is_vip) {
                $amount = $entity->price * $discount;
            } else {
                $amount = $entity->price;
            }
            $subject = $entity->title;
        } else if($product_type == Order::PRODUCT_TYPE_VIP){
            $model = new PackageSetting();
            $entity = $model->find($entity_id);
            $entity->price = $amount = $entity->month * $entity->month_price;
            $subject = '购买VIP会员' . $entity->month . "个月";
        } else {
            $amount =  Config::getDarenAmount() * 100;
            $subject = '开通达人权益';
        }


        $amount_yuan = round($amount / 100, 2) ;
        if ( $amount_yuan < 0.01) {
            throw new \Exception('订单金额小于0.01元');
        }
        //抖音支付
        if ($benefit_user == User::PLAT_DY) {
            $wx_pay_url = $ali_pay_url = '';
            $order = [
                'out_trade_no' => $out_trade_no,
                'total_amount' => $amount_yuan,
                'subject' => $subject,
            ];
            $ali_pay_url = $self->payApp()->app($order)->getContent();

            $config = [
                'out_trade_no' => $out_trade_no,
                'total_fee' => $amount,
                'body' => $subject,
                'spbill_create_ip' => get_client_ip(),
                'trade_type' => 'MWEB',
                'scene_info' => json_encode_cn([
                    'h5_info' => [
                        'type' => 'Wap',
                        'wap_url' => 'http://www.chuyouhui.top',
                        'wap_name' => $subject
                    ]
                ])
            ];
            $wx_pay_url = $self->payWx()->wap($config)->getTargetUrl();

            $app = $self->ttMini();
            $uid = $user->openid;

            $response = $app->payment->pay($uid, $out_trade_no, $amount_yuan * 100, $subject, [
                'body' => $subject,
                'alipay_url' =>  $ali_pay_url,
                'wx_url' => $wx_pay_url,
                'valid_time' => '300',
                'notify_url' => 'http://www.chuyouhui.top',
                'risk_info' => ''
            ]);
        } else { //微信支付
            $config = [
                'out_trade_no' => $out_trade_no,
                'total_fee' => $amount,
                'body' => $subject,
                'openid' => $user->openid,
                'trade_type' => 'JSAPI'
            ];
            $response = $self->payWx()->miniapp($config);
        }


        \DB::transaction(function () use($out_trade_no, $user_id, $entity, $amount_yuan, $pay_type, $product_type, $user){

            if ($product_type == Order::PRODUCT_TYPE_VIP) {
                $data = [
                    'user_id' => $user_id,
                    'benefit_user' => $user->benefit_user,
                    'order_sn' => $out_trade_no,
                    'rec_merchant_id' => $user->rec_merchant_id,
                    'origin_amount' => $entity->price,
                    'paid_amount' => $amount_yuan * 100,
                    'pay_type' => $pay_type,
                    'product_type' => $product_type,
                    'month' => $entity->month,
                    'month_price' => $entity->month_price
                ];
            } else if ($product_type == Order::PRODUCT_TYPE_COOKBOOK) {
                $data = [
                    'user_id' => $user_id,
                    'benefit_user' => $user->benefit_user,
                    'merchant_id' => $entity->merchant_id,
                    'rec_merchant_id' => $user->rec_merchant_id,
                    'cookbook_id' => $entity->id,
                    'category_id' => $entity->category_id,
                    'order_sn' => $out_trade_no,
                    'origin_amount' => $entity->price,
                    'paid_amount' => $amount_yuan * 100,
                    'product_type' => $product_type
                ];
            } else {
                $data = [
                    'user_id' => $user_id,
                    'benefit_user' => $user->benefit_user,
                    'rec_merchant_id' => $user->rec_merchant_id,
                    'order_sn' => $out_trade_no,
                    'origin_amount' => $amount_yuan * 100,
                    'paid_amount' => $amount_yuan * 100,
                    'product_type' => $product_type
                ];
            }

            if ($product_type == Order::PRODUCT_TYPE_COOKBOOK) {

                //生成快照表
                $arr = $entity->toArray();
                unset($arr['id'], $arr['price_yuan'], $arr['vip_price_yuan']);
                $snapshot = new CookbookSnapshot();
                foreach ($arr as $key => $value) {
                    $snapshot-> {$key} = $value;
                }
                $snapshot->save();
                $data['cookbook_snopshot_id'] = $snapshot->id;

            }

            Order::create($data);

        });

        return $response;
    }

    public static function pay_result($out_trade_no, $total_amount, $trade_no, $pay_type) {
        try {
            \DB::transaction(function () use($out_trade_no, $total_amount, $trade_no, $pay_type){
                $prefix = substr($out_trade_no, 0, 1);
                $title = '';
                //防止
                if ($prefix == 'm') {
                    $user_id = MallOrder::where('pay_order_sn', $out_trade_no)->value('user_id');
                    $list = MallOrder::where('pay_order_sn', $out_trade_no)->get();
                    if (!$list) {
                        throw new \Exception('订单号不存在');
                    }
                    foreach ($list as $order) {
                        $order = MallOrder::lockForUpdate()->find($order->id);
                        if ($order->status != MallOrder::STATUS_WAIT_PAY) {
                            return;
                        }
                        $status =  MallOrder::STATUS_WAIT_PRODUCT;

                        $order->out_trade_no = $trade_no;
                        $order->status = $status;
                        $order->paid_at = date('Y-m-d H:i:s');
                        $order->pay_type = $pay_type;
                        $order->save();

//                        if ($order->union_total_amount != $total_amount) {
//                            throw new \Exception('订单金额不正确');
//                        }

                        //判断是否包含零元购商品
                        $is_include_zero = MallOrderProduct::where('order_id', $order->id)->where('is_zero', 1)->exists();
                        if ($is_include_zero && $user_id) {
                            User::where('id', $user_id)->where('has_buy_zero_product', 0)->update(['has_buy_zero_product' => 1]);
                        }

                        MallOrderProduct::where('order_id', $order->id)->update([
                            'status' => MallOrderProduct::STATUS_WAIT_PRODUCT,
                            'pay_type' => $pay_type
                        ]);

                        //平均分配运费
                        $list = MallOrderProduct::where('order_id', $order->id)->where('is_zero', 0)->get();
                        $arr_amount = $list->pluck('paid_amount', 'id')->all();
                        $sum = array_sum($arr_amount);
                        $count = count($arr_amount);
                        $arr_fare = [];

                        $i = 0;
                        foreach ($arr_amount as $key => $amount) {
                            if ($i+1 == $count)
                                break;
                            $arr_fare[$key] = floor (($amount/ $sum) * $order->fare);
                            $i++;
                        }
                        $arr_fare[$key] = $order->fare - array_sum($arr_fare);

                        foreach ($list as $k => $one) {
                            $one->assign_fare = $arr_fare[$one->id];
                            $one->save();
                        }


                        //流水
                        UnionOrder::create([
                            'user_id' => $order->user_id,
                            'order_id' => $order->id,
                            'type' => UnionOrder::TYPE_MALL,
                            'order_sn' => $order->order_sn,
                            'amount' => $order->paid_amount,
                            'created_at' => $order->created_at
                        ]);
                    }


                } else {
                    $order = Order::where('order_sn', $out_trade_no)->first();
                    if ($order->cookbook_snopshot_id) {
                        $cookbook = CookbookSnapshot::find($order->cookbook_snopshot_id);
                        $title = $cookbook->title ?? '';
                    }
                    \Log::info(date('Y-m-d H:i:s'));
                    if (!$order) {
                        throw new \Exception('订单号不存在');
                    }

                    $order = Order::lockForUpdate()->find($order->id);
                    if ($order->status == Order::PAID_SUCCESS) {
                        return;
                    }
                    $status =  Order::PAID_SUCCESS;

                    if ($order->paid_amount != $total_amount) {
                        throw new \Exception('订单金额不正确');
                    }
                    $order->out_trade_no = $trade_no;
                    $order->status = $status;
                    $order->pay_type = $pay_type;
                    $order->save();

                }

                if ($prefix != 'm') {
                    $user = User::find($order->user_id);
                    if ($order->product_type == ORDER::PRODUCT_TYPE_VIP) {
                        $vip_expired_at = $user->vip_expired_at ?: 0;
                        if ($vip_expired_at) {
                            if (strtotime($vip_expired_at) >= time()) {
                                $vip_expired_at = date('Y-m-d', strtotime("+1year", strtotime($vip_expired_at)));
                            } else {
                                $vip_expired_at = date('Y-m-d', strtotime("+1year", time()));
                            }
                        } else {
                            $vip_expired_at = date('Y-m-d', strtotime("+1year", time()));
                        }
                        $order->extra = $vip_expired_at;
                        $order->save();

                        $user->is_vip = 1;
                        $user->vip_expired_at = $vip_expired_at;
                        $user->save();

                        //同时增加引荐人的佣金
                        if ($merchant_id = $user->rec_merchant_id) {
                            $title = '会员开通';
                            BalanceService::store($user->benefit_user, $order->user_id, $merchant_id, $total_amount, Balance::TYPE_VIP, $order->id, $order->order_sn, $title);
                        }
                        $type = UnionOrder::TYPE_VIP;
                    } else if ($order->product_type == ORDER::PRODUCT_TYPE_COOKBOOK) {
                        //增加收入
                        if ($merchant_id = $user->rec_merchant_id) {
                            BalanceService::store($user->benefit_user, $order->user_id, $merchant_id, $total_amount, Balance::TYPE_COOKBOOK_REC, $order->id, $order->order_sn, $title);
                        }
                        BalanceService::store($user->benefit_user, $order->user_id, $order->merchant_id, $total_amount, Balance::TYPE_COOKBOOK, $order->id, $order->order_sn, $title);

                        $type = UnionOrder::TYPE_COOKBOOK;
                    } else {
                        $daren_expired_at = $user->daren_expired_at ?: 0;
                        $type = UnionOrder::TYPE_DAREN;
                        if ($daren_expired_at) {
                            if (strtotime($daren_expired_at) >= time()) {
                                $daren_expired_at = date('Y-m-d', strtotime("+1year", strtotime($daren_expired_at)));
                            } else {
                                $daren_expired_at = date('Y-m-d', strtotime("+1year", time()));
                            }
                        } else {
                            $daren_expired_at = date('Y-m-d', strtotime("+1year", time()));
                        }
                        $order->extra = $daren_expired_at;
                        $order->save();

                        $user->is_daren = 1;
                        $user->daren_expired_at = $daren_expired_at;

                        //同时给用户开通vip + 1年
                        $vip_expired_at = $user->vip_expired_at ?: 0;
                        if ($vip_expired_at) {
                            if (strtotime($vip_expired_at) >= time()) {
                                $vip_expired_at = date('Y-m-d', strtotime("+1year", strtotime($vip_expired_at)));
                            } else {
                                $vip_expired_at = date('Y-m-d', strtotime("+1year", time()));
                            }
                        } else {
                            $vip_expired_at = date('Y-m-d', strtotime("+1year", time()));
                        }


                        $entity = PackageSetting::where('month', 12)->first();
                        $amount = $entity->month * $entity->month_price;

                        Order::create([
                            'user_id' => $user->id,
                            'benefit_user' => $user->benefit_user,
                            'rec_merchant_id' => $user->rec_merchant_id,
                            'order_sn' => create_order_no('v'),
                            'origin_amount' => $amount,
                            'paid_amount' => 0,
                            'status' => Order::PAID_SUCCESS,
                            'pay_type' => Order::PAY_DAREN_SEND_VIP,
                            'product_type' => Order::PRODUCT_TYPE_VIP,
                            'month' => $entity->month,
                            'month_price' => $entity->month_price,
                            'extra' => $vip_expired_at
                        ]);
                        $user->is_vip = 1;
                        $user->vip_expired_at = $vip_expired_at;

                        $user->save();
                    }

                    //流水
                    UnionOrder::create([
                        'user_id' => $order->user_id,
                        'order_id' => $order->id,
                        'type' => $type,
                        'order_sn' => $order->order_sn,
                        'amount' => $order->paid_amount,
                        'created_at' => $order->created_at
                    ]);

                }

            });
        }catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }

    }



}
